#include "scheduler.h"

Scheduler :: Scheduler (Print_Buffer * p_buff) {
	pb = p_buff;
	gs = NULL;
	choice = MFQS;

	// RTS Option Defaults
	is_soft = true;

	// MFQS Option Defaults
	num_queues = 3;
	max_queues = 5;
	time_quantum_base = 7;
	age_time = 20;

	// HWS Option Defaults
	time_quantum = 3;
}

Scheduler :: ~Scheduler () {

}

void Scheduler :: settings_menu () {
	bool keep_going = true;
	int menu_choice = 0;

	while (keep_going) {
		menu_choice = list_options ();
		do_option (menu_choice, & keep_going);
	}
}

void Scheduler :: print_settings () {
	cout << "Type of scheduler: ";

	if (choice == MFQS) {
		cout << "MFQS" << endl;
		cout << "Number of queues: " << num_queues << endl;
		cout << "Time quantum base: " << time_quantum_base << endl;
		cout << "Ageing time: " << age_time << endl;
		cout << endl;

	} else if (choice == RTS) {
		cout << "RTS" << endl;
		cout << "Mode: ";

		if (is_soft) {
			cout << "Soft" << endl;
		} else {
			cout << "Hard" << endl;
		}

		cout << endl;

	} else if (choice == HWS) {
		cout << "HWS" << endl;
		cout << "Number of clock ticks: " << time_quantum << endl;

	} else {
		cerr << "Something is wrong here..." << endl;
		exit (1);
	}
}

void Scheduler :: run (string input_file) {
	if (choice == MFQS) {
		gs = new Scheduler_MFQS (num_queues, time_quantum_base, age_time);
	} else if (choice == RTS) {
		//gs = new Scheduler_RTS (is_soft);
	} else if (choice == HWS) {
		gs = new Scheduler_HWS (time_quantum);
	}

	gs -> read_in (input_file);
	gs -> sort_processes ();
	gs -> start ();
	gs -> show_gantt ();

	delete gs;
}

int Scheduler :: list_options () {
	int result = 0;

	cout << "Options:" << endl;
	cout << "0. Change scheduling algorithm" << endl;
	cout << "1. Change algorithm settings" << endl;
	cout << "2. Go back" << endl;

	cout << endl << "Choice: ";
	cin >> result;
	cout << endl;

	return result;
}

void Scheduler :: do_option (int input, bool * keep_going) {
	if (input == 0) {
		int alg = 0;
		cout << "Choose an algorithm to run:" << endl;
		cout << "0. MFQS" << endl;
		cout << "1. RTS" << endl;
		cout << "2. HWS" << endl;

		cout << endl << "Choice: ";
		cin >> alg;
		cout << endl;

		if (alg == 0) {
			choice = MFQS;
		} else if (alg == 1) {
			choice = RTS;
		} else if (alg == 2) {
			choice = HWS;
		} else {
			cerr << "Invalid choice." << endl;
		}
	} else if (input == 1) {
		if (choice == MFQS) {
			menu_mfqs ();
		} else if (choice == RTS) {
			menu_rts ();
		} else if (choice == HWS) {
			menu_hws ();
		}
	} else if (input == 2) {
		* keep_going = false;
	} else {
		cerr << "Unknown scheduler menu option" << endl;
		exit (1);
	} 
}

void Scheduler :: menu_mfqs () {
	cout << "Number of queues: ";
	cin >> num_queues;

	if (num_queues > max_queues) {
		cout << "Input too high, setting it to 5" << endl;
		num_queues = 5;
	} else if (num_queues < 1) {
		cout << "Number not valid, setting it to 1" << endl;
		num_queues = 1;
	}

	cout << "Base Time Quantum: ";
	cin >> time_quantum_base;

	if (time_quantum_base < 1) {
		cout << "Number not valid, setting it to 1" << endl;
		time_quantum_base = 1;
	}

	cout << "Ageing time: ";
	cin >> age_time;

	if (time_quantum_base < 1) {
		cout << "Number not valid, setting it to 1" << endl;
		age_time = 1;
	}

	cout << endl;
}

void Scheduler :: menu_rts () {
	char input;
	cout << "Enable hard scheduling? (y/n) ";
	cin >> input;

	if (input == 'y') {
		is_soft = false;
	} else if (input == 'n') {
		is_soft = true;
	} else {
		cerr << "Unknown input, setting mode to soft" << endl;
		is_soft = true;
	}

	cout << endl;
}

void Scheduler :: menu_hws () {
	cout << "How many clock ticks should a process run? ";
	cin >> time_quantum;
	cout << endl;
}

